package com.gmail.bogatyr.alexander.dao;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;

import java.io.Serializable;
import java.util.Collection;

/**
 * This class represents...
 */
public abstract class BaseDao<T extends Serializable, V extends Serializable> {

    private static final SessionFactory ourSessionFactory;
    private static final ServiceRegistry serviceRegistry;

    static {
        try {
            Configuration configuration = new Configuration();
            configuration.configure();

            serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
            ourSessionFactory = configuration.buildSessionFactory(serviceRegistry);
        } catch (Throwable ex) {
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static Session getSession() throws HibernateException {
        return ourSessionFactory.openSession();
    }

    private Class<T> clazz;

    public BaseDao(final Class<T> clazz) {
        this.clazz = clazz;
    }

    public T findById(final V id) {
        return (T) getSession().get(clazz, id);
    }

    public Collection<T> findAll() {
        Criteria sc = getSession().createCriteria(clazz);
        return sc.list();
//        return getSession().createQuery("from " + clazz.getName()).list();
    }

    public Serializable save(final T entity) {
        getSession().persist(entity);
        return 111L;
    }

    public T update(final T entity) {
        return (T) getSession().merge(entity);
    }

    public void delete(final T entity) {
        getSession().delete(entity);
    }

    public void deleteById(final V id) {
        final T entity = findById(id);
        delete(entity);
    }

    @Override
    protected void finalize() throws Throwable {
//        if(getSession().isOpen()) getSession().close();
        super.finalize();
    }
}
